home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / BROWSERS / STIK / STIKCOVL / CABOVL.C next >
Encoding:
C/C++ Source or Header  |  1996-02-10  |  22.0 KB  |  744 lines

  1. #ifdef MDEBUG
  2.     #define DEBUG
  3. #endif
  4.  
  5. #ifdef DEBUG
  6.     #define ERR_MSGS
  7. #endif
  8.  
  9. /* 
  10. ** init.c for Inet-Module
  11. ** Initialisation for HTML.APP browser inet-module
  12. ** 
  13. ** Copyright (C) 1995, Stephane Boisson. All Rights reserved.
  14. ** Login <boisson@worldnet.net>
  15. ** 
  16. ** Started on  Sun Aug 27 23:41:30 1995 Stephane Boisson
  17. ** Last update Mon Aug 28 00:44:10 1995 Stephane Boisson
  18. ** 
  19. ** This file can be redistributed under the terms of the GNU General
  20. ** Public Licence.
  21. */
  22.  
  23. /* Includes for Cab. */
  24. /* #include <unistd.h> */
  25. #include "module.h"
  26.  
  27. /* Includes for STiK. */
  28. #include "transprt.h"
  29.  
  30. /* Includes for me... :-) */
  31. #include "http.h"
  32. #include <stdio.h>
  33. #include <string.h>
  34. #include <tos.h>
  35. #include <ext.h>
  36. #include "stdlib.h"
  37. #include "time.h"
  38.  
  39.  
  40. /*--- Prototypes ---*/
  41. /* For Cab */
  42. long ___CDECL init_module(url_methods_t *out, browser_info_t *in, char *path);
  43. long ___CDECL get_url_info(char *url, long *timep, long *sizep, char *type);
  44. void ___CDECL get_version(char **authorp, long *versionp, long *datep);
  45. long ___CDECL get_url(char *url, char *filename);
  46. long ___CDECL post(char *url,char *content, char *enctype, char *filename);
  47. void ___CDECL restore_module(void);
  48. /* For me */
  49. int parse_header(char header[], URL_info *info);
  50. time_t parse_date(char *date_string);
  51. void clear_info(URL_info *info);
  52. void split_URL(char *URL, URL_components *components);
  53. static long init_drivers(void);
  54. int http_proxy_cfg(char *ps, int pslen, int *pp);int ftp_proxy_cfg(char *ps, int pslen, int *pp);int16 open_connection(char *server, int port, int TOS);
  55. long http_get(char *URL, char *content, char *enctype, char *file, int method);
  56.  
  57. /*--- Global variables ---*/
  58. /* For Cab */
  59. browser_info_t *browser;
  60. /* For STiK */
  61. DRV_LIST *drivers = (DRV_LIST *)NULL;
  62. TPL *tpl = (TPL *)NULL;
  63. /* For me */
  64. static char user_agent[256];
  65.  
  66. /* ----------------------------------------------------------------- ** 
  67. ** init_module - Initialize the module (called by browser)           ** 
  68. ** ----------------------------------------------------------------- */
  69. long ___CDECL init_module(out, in, path)
  70. url_methods_t *out;    /* struture to fill */
  71. browser_info_t *in;    /* infos about browser */
  72. char *path;        /* module path, '\' terminated */
  73. {
  74.     int ftp_proxy_port;
  75.     char ftp_proxy[256];
  76.  
  77.   /*--- Set browser info variable ---*/
  78.   browser = in;
  79.  
  80.   /*--- Fill URL methods structure ---*/
  81. /*  out->restore = restore_module;*/
  82.   out->get_url = get_url;
  83. /*  out->get_url_info = get_url_info;*/
  84.   out->get_version = get_version;
  85.   out->post = post;
  86.  
  87.   /*--- Initialize other stuffs here ---*/
  88.     Supexec(init_drivers);
  89.  
  90.     /* See if we got a value. */
  91.     if (drivers == (DRV_LIST *)NULL) {
  92.         #ifdef MDEBUG
  93.             Cconws("STiK is not loaded\r\n");
  94.         #endif
  95.         return (0);
  96.     }
  97.  
  98.     /* Check Magic number    */
  99.     if (strcmp(MAGIC, drivers->magic)) {
  100.         /* Cconws("Magic string doesn't match!\r\n"); */
  101.         return (0);
  102.     }
  103.  
  104.     /* the "TRANSPORT" layer
  105.      * driver.  If this seems unnecessarily complicated, it's
  106.      * because I tried to create today, what I would like to
  107.      * use later on.  In future, there will be multiple
  108.      * drivers accessible via this method.  With luck, your
  109.      * code will still work with future versions of my software.
  110.      */
  111.  
  112.     tpl = (TPL *)get_dftab(TRANSPORT_DRIVER);
  113.     if (tpl == (TPL *)NULL) {
  114.         /* Cconws("Transport layer *not* loaded\r\n"); */
  115.         return (0);
  116.     }
  117.     sprintf(user_agent, "User-Agent: Cab/0.96  STiK/%s\r\n", tpl->version);
  118.  
  119.   /*--- Return support ---*/
  120.     if (ftp_proxy_cfg(ftp_proxy, 256, &ftp_proxy_port)==TRUE)
  121.         return(SUPPORT_HTTP|SUPPORT_FTP);
  122.  
  123.   return(SUPPORT_HTTP);
  124. }
  125.  
  126.  
  127. /* ----------------------------------------------------------------- ** 
  128. ** get_version - Returns infos about module                          ** 
  129. ** ----------------------------------------------------------------- */
  130. void ___CDECL get_version(authorp, versionp, datep)
  131. char **authorp;    /* 4x30 chars separated by '|' */
  132. long *versionp;    /* Version number in BCD format (V1.15 -> 0x00011500) */
  133. long *datep;    /* Date in BCD format (0xYYYYMMDD) */
  134. {
  135.   *versionp = 0x00011000L;
  136.   *datep = 0x19951021L;
  137.   *authorp =
  138.       "Tim Newsome|http://www.cybercomm.net/~drz/|drz@raven.cybercomm.net";
  139. }
  140.  
  141.  
  142. /* ----------------------------------------------------------------- ** 
  143. ** restore_module - De-initialization                                ** 
  144. **                  (freeing memory, closing files, etc...)          ** 
  145. ** ----------------------------------------------------------------- */
  146. void ___CDECL restore_module()
  147. {
  148. }
  149.  
  150.  
  151. /* ----------------------------------------------------------------- ** 
  152. ** get_url - Fetch URL and write it as a HTML file                   ** 
  153. **           Returns 0 if OK, else `errno'                           **
  154. ** ----------------------------------------------------------------- */
  155. long ___CDECL get_url(url, filename)
  156. char *url;        /* URL to fetch */
  157. char *filename;        /* file to write to */
  158. {
  159.     #ifdef MDEBUG
  160.         printf("%cH\n\n", 27);    /* home the cursor */
  161.     #endif
  162.   return(http_get(url, "", "", filename, GET_METHOD));
  163. }
  164.  
  165. long http_get(URL, content, enctype, file, method)
  166. char *URL;
  167. char *content;
  168. char *enctype;
  169. char *file;
  170. int method;
  171. {
  172.     int16 x, cn;
  173.     time_t timeout;
  174.  
  175.     URL_info info;
  176.     URL_components URL_comps;
  177.     DOSTIME filetime;
  178.     struct tm *urltime;
  179.     char header[2048], buffer[512], my_header[2048], http_proxy[256];
  180.     char new_file[1024];
  181.     char *new_file_ptr;
  182.     int file_handle, status=1, header_pos=0, http_proxy_port;
  183.     long bytes_read=0, return_code=0;
  184.     int bytes_available, eof=0;
  185.     int proxy;
  186.  
  187.     #ifdef DEBUG
  188.         printf("%cH\n\n", 27);    /* home the cursor */
  189.     #endif
  190.  
  191.     #ifdef DEBUG
  192.         printf("URL: \"%s\"\nFile: \"%s\" \n", URL, file);
  193.     #endif
  194.  
  195.     split_URL(URL, &URL_comps);
  196.  
  197.     proxy=http_proxy_cfg(http_proxy, 256, &http_proxy_port);
  198.     #ifdef MDEBUG
  199.         if (proxy==TRUE)
  200.             printf("Using %s:%d as proxy.", http_proxy, http_proxy_port);
  201.     #endif
  202.  
  203.     if (proxy==TRUE) {
  204.         strncpy(URL_comps.server, http_proxy, 256);
  205.         URL_comps.port=http_proxy_port;
  206.     }
  207.     #ifdef MDEBUG
  208.         printf("That's %s:%d.\n", URL_comps.server, URL_comps.port);
  209.     #endif
  210.  
  211.     /* Get the stuff and stick it in a file. */
  212.     file_handle=(int) Fcreate(file, 0);
  213.     if (file_handle<0) {
  214.         #ifdef ERR_MSGS
  215.             printf("Couldn't create %s!\n", file);
  216.         #endif
  217.         return(1);
  218.     }
  219.  
  220.     cn=open_connection(URL_comps.server, URL_comps.port, 0);
  221.  
  222.     #ifdef MDEBUG
  223.         printf("open_connection() returned %i\n", cn);
  224.     #endif
  225.     if (cn<0) {
  226.         #ifdef ERR_MSGS
  227.             printf("open_connection() returns: %s\n", get_err_text(cn));
  228.         #endif
  229.         Fclose(file_handle);
  230.         return(1);
  231.     }
  232.  
  233.     #ifdef MDEBUG
  234.         printf("Creating header...\n");
  235.         if(method==POST_METHOD) {
  236.             printf("enctype: %s\n", enctype);
  237.             printf("strlen(content): %ld\n", strlen(content));
  238.         }
  239.     #endif
  240.     if (method==GET_METHOD) {
  241.         if (proxy==TRUE)
  242.             sprintf(my_header, "GET %s HTTP/1.0\r\n%s\r\n", URL, user_agent);
  243.         else
  244.             sprintf(my_header, "GET %s HTTP/1.0\r\n%s\r\n", URL_comps.URI, user_agent);
  245.     } else if (method==POST_METHOD) {
  246.         if (proxy==TRUE)
  247.             sprintf(my_header, "POST %s HTTP/1.0\r\nContent-Length: %ld\r\nContent-Encoding: %s\r\n%s\r\n\r\n",
  248.                 URL, strlen(content), enctype, user_agent);
  249.         else
  250.             sprintf(my_header,
  251.                 "POST %s HTTP/1.0\r\nContent-Length: %ld\r\nContent-Encoding: %s\r\n%s\r\n\r\n",
  252.                 URL_comps.URI, strlen(content), enctype, user_agent);
  253.         #ifdef MDEBUG
  254.             printf("%s", my_header);
  255.         #endif
  256.     }
  257.     browser->msg_status(5, 0);    /* Sending request... */
  258.     TCP_send(cn, my_header, (int16) strlen(my_header));
  259.     if (method==POST_METHOD) {
  260.         #ifdef MDEBUG
  261.             printf("Sending %ld bytes using the POST method.\n", strlen(content));
  262.         #endif
  263.         TCP_send(cn, content, (int16) strlen(content));
  264.     }
  265.  
  266.     timeout=clock()+120*CLK_TCK;    /* 120 second timeout */
  267.  
  268.     browser->msg_status(2,0);    /* Getting data... */
  269.     while (eof==0) {
  270.         bytes_available=CNbyte_count(cn);
  271.         if (Bconstat(2)==-1 && (Bconin(2) & 0xFF)==27) {
  272.             eof=4;
  273.         } if (clock()>timeout) {
  274.             eof=2;
  275.             #ifdef MDEBUG
  276.                 printf("Timeout!\n");
  277.             #endif
  278.         } else if (bytes_available==E_EOF) {
  279.             #ifdef MDEBUG
  280.                 printf("EOF!\n");
  281.             #endif
  282.             eof=1;
  283.         } else if (bytes_available<E_NODATA) {
  284.             #ifdef ERR_MSGS
  285.                 printf("CNbyte_count() returns: %s\n", get_err_text(bytes_available));
  286.             #endif
  287.             eof=3;
  288.         } else if (bytes_available>0) {
  289.             timeout=clock()+60*CLK_TCK;    /* timeout 60s after last char */
  290.             if (status==2) {
  291.                 if (CNget_block(cn, buffer, bytes_available)>=E_NODATA) {
  292.                     Fwrite(file_handle, bytes_available, &buffer);
  293.                     bytes_read+=bytes_available;
  294.                     browser->msg_status(2, bytes_read);
  295.                 } else {
  296.                     #ifdef ERR_MSGS
  297.                         printf("Error in CNget_block()!\n");
  298.                     #endif
  299.                     eof=3;
  300.                 }
  301.             } else {
  302.                 x = CNget_char(cn);
  303.                 if (x<E_NODATA) {
  304.                     #ifdef ERR_MSGS
  305.                         printf("CNget_char() returns: %s\n", get_err_text(x));
  306.                     #endif
  307.                     eof=3;
  308.                 } else
  309.                     header[header_pos++]=(char) x;
  310.             }
  311.             if (status==1) {
  312.                 if (strncmp(&header[header_pos-4], "\r\n\r\n", 4)==0 ||
  313.                     strncmp(&header[header_pos-4], "\n\r\n\r", 4)==0 ||
  314.                     strncmp(&header[header_pos-2], "\r\r", 2)==0 ||
  315.                     strncmp(&header[header_pos-2], "\n\n", 2)==0) {
  316.                     header[header_pos]=0;
  317.                     #ifdef MDEBUG
  318.                         printf("End of header.\n");
  319.                     #endif
  320.                     status++;
  321.                 } else if (header_pos>2000) {
  322.                     Fwrite(file_handle, header_pos, header);
  323.                     status++;
  324.                 }
  325.             }
  326.         }
  327.     }
  328.  
  329.     if (eof>1) {    /* timeout or worse*/
  330.         x = (int16)TCP_close(cn, 2);
  331.         if (x < 0) {
  332.             #ifdef MDEBUG
  333.                 printf("TCP_close() returns: %s\n", get_err_text(x));
  334.             #endif
  335.         }
  336.         #ifdef MDEBUG
  337.             printf("Fclose returns %i\n", Fclose(file_handle));
  338.         #else
  339.             /**** I might get a bug here! ****/
  340.             if((x=Fclose(file_handle))<0) {
  341.                 #ifdef ERR_MSGS
  342.                     printf("Error with Fclose! (%i)\n", x);
  343.                 #endif
  344.             }
  345.         #endif
  346.         return(eof);
  347.     }
  348.  
  349.     x = (int16)TCP_close(cn, 2);
  350.     if (x<E_EOF) {
  351.         #ifdef ERR_MSGS
  352.             printf("TCP_close() returns: %s\n", get_err_text(x));
  353.         #endif
  354.     }
  355.  
  356.     #ifdef MDEBUG
  357.         printf("Parsing header...\n");
  358.     #endif
  359.     if ((x=parse_header(header, &info))!=FALSE) {
  360.         if (info.last_modified>info.date) {
  361.             urltime=gmtime(&(info.last_modified));
  362.             #ifdef MDEBUG
  363.                 printf("%s", ctime(&(info.last_modified)));
  364.             #endif
  365.         } else {
  366.             urltime=gmtime(&(info.date));
  367.             #ifdef MDEBUG
  368.                 printf("%s", ctime(&(info.date)));
  369.             #endif
  370.         }
  371.         #ifdef MDEBUG
  372.             printf("%s", asctime(urltime));
  373.         #endif
  374.  
  375.         filetime.time=(urltime->tm_sec)/2;
  376.         filetime.time+=(urltime->tm_min)<<5;
  377.         filetime.time+=(urltime->tm_hour)<<11;
  378.         filetime.date=(urltime->tm_mday);
  379.         filetime.date+=((urltime->tm_mon)+1)<<5;
  380.         filetime.date+=((urltime->tm_year)-80)<<9;
  381.         Fdatime(&filetime, file_handle, 1);
  382.  
  383.         if (strlen(info.location)>0) {
  384.             #ifdef DEBUG
  385.                 printf("Location: %s\n", info.location);
  386.             #endif
  387.             if (browser->new_url(info.location, &new_file_ptr)==0) {
  388.                 return_code=-1;
  389.                 strcpy(new_file, new_file_ptr);
  390.             }
  391.         }
  392.     }
  393.  
  394.     #ifdef MDEBUG
  395.         printf("Fclose returns %d\n", Fclose(file_handle));
  396.     #else
  397.         if((x=Fclose(file_handle))<0)
  398.             browser->msg_error(x);
  399.     #endif
  400.  
  401.     if (return_code==-1) {        /* get the info from elsewhere */
  402.         #ifdef DEBUG
  403.             printf("Get %s as %s\n", info.location, new_file);
  404.         #endif
  405.         if (method==GET_METHOD)
  406.             return_code=get_url(info.location, new_file);
  407.         else if (method==POST_METHOD)
  408.             return_code=post(info.location, content, enctype, new_file);
  409.         /*Fdelete(file);*/
  410.     }/* else if (return_code!=0)
  411.         Fdelete(file);*/
  412.     #ifdef MDEBUG
  413.         printf("Hit a key.\n");
  414.         Bconin(2);
  415.     #endif
  416.     return(return_code); /* return(0)     if getting data was successful,     */
  417.               /* return(errno) if it fails, return an error number */
  418. }
  419.  
  420.  
  421. /* ----------------------------------------------------------------- ** 
  422. ** post    - Post FORM, fetch result and write it as a HTML file     ** 
  423. **           Returns 0 if OK, else `errno'                           **
  424. ** ----------------------------------------------------------------- */
  425. long ___CDECL post(url, content, enctype, filename)
  426. char *url;             /* URL to fetch */
  427. char *content;      /* data to post */
  428. char *enctype;      /* format of data */
  429. char *filename;        /* file to write to */
  430. {
  431.     #ifdef MDEBUG
  432.         printf("%cH\n\n", 27);    /* home the cursor */
  433.         printf("url: %s\ncontent: %s\nenctype: %s\nfilename: %s\n",
  434.             url, content, enctype, filename);
  435.     #endif
  436.   return(http_get(url, content, enctype, filename, POST_METHOD));
  437. }
  438.  
  439.  
  440. /* ----------------------------------------------------------------- ** 
  441. ** get_url_info - Retreive infos for an URL                          ** 
  442. **                Returns 0 if OK, else `errno'                      **
  443. ** ----------------------------------------------------------------- */
  444. long ___CDECL get_url_info(url, timep, sizep, type)
  445. char *url;    /* URL */
  446. long *timep;    /* UNIX time */
  447. long *sizep;    /* size of data */
  448. char *type;    /* mime type (max len = 250), empty string if unknow */
  449. {
  450.   return 0;
  451. }
  452.  
  453.  
  454. /* ----------------------------------------------------------------- ** 
  455. ** main - Doesn't useful, but take care that others functions don't  ** 
  456. **        get `swallowed' by compiler optimizations                  ** 
  457. ** ----------------------------------------------------------------- */
  458. int main()
  459. {
  460.   static void *array[] = {
  461.     "Needs HTML.APP to run\r\n",
  462.     (void *)BROWSER_MAGIC1, (void *)BROWSER_MAGIC2,
  463.     (void *)BROWSER_MAGIC3, (void *)BROWSER_MAGIC4, init_module};
  464.   
  465.   write(1, array[0], strlen(array[0]));
  466.   return 1;
  467. }
  468.  
  469. /************************************************************************
  470.     This is where my private routines start
  471. ************************************************************************/
  472.  
  473. int parse_header(char header[], URL_info *info)
  474. {
  475.     char field[256], entry[256], line[512], tmp[4];
  476.     int header_pos=0, line_pos, return_code=0, line_number=0;
  477.     size_t index;
  478.     double http_version=0;
  479.     int eoh=0;
  480.  
  481.     clear_info(info);
  482.  
  483.     #ifdef MDEBUG
  484.         printf("Let's go! (%d)\n", eoh);
  485.     #endif
  486.  
  487.     while (eoh==0) {
  488.         /* Get a full line */
  489.         #ifdef MDEBUG
  490.             printf("Get line...\n");
  491.         #endif
  492.         for (line_pos=0; header[header_pos]!='\n' &&
  493.                           header[header_pos]!='\r'; header_pos++) {
  494.             line[line_pos++]=header[header_pos];
  495.         }
  496.         /* If it's a /r/n or /n/r combo, then increment header_pos twice
  497.          * so we don't get a zero-length line next time... */
  498.         if ((header[header_pos+1]=='\n' && header[header_pos]=='\r') ||
  499.             (header[header_pos+1]=='\r' && header[header_pos]=='\n')) {
  500.             header_pos+=2;
  501.             #ifdef MDEBUG
  502.                 printf("Skipping two...");
  503.             #endif
  504.         } else {
  505.             header_pos++;
  506.             #ifdef MDEBUG
  507.                 printf("Skipping one...");
  508.             #endif
  509.         }
  510.         line[line_pos]=0;
  511.         #ifdef MDEBUG
  512.             printf("%s (%d)\n", line, (int) strlen(line));
  513.         #endif
  514.  
  515.         if (line_pos==0)
  516.             eoh=1;
  517.         else if (line_number++==0) {
  518.             /* HTTP header, not a field. */
  519.             tmp[3]=0;
  520.             if (strncmp("HTTP/", line, 5)==0) {
  521.                 http_version=atof(strncpy(tmp, &line[5], 3));
  522.             }
  523.             if (http_version==1.0) {
  524.                 return_code=atoi(strncpy(tmp, &line[9], 3));
  525.             } else {
  526.                 return_code=FALSE;
  527.             }
  528.         } else {
  529.             /* Copy all bytes up to and not including the ":" into field[] */
  530.             index=strcspn(line, ":");
  531.             if (index>0) {
  532.                 strncpy(field, line, index);
  533.                 field[index]=0;
  534.     
  535.                 /* Copy the rest into entry[] */
  536.                 strcpy(entry, &line[index+2]);
  537.                 
  538.                 #ifdef MDEBUG
  539.                     printf("%s: %s\n", field, entry);
  540.                 #endif
  541.     
  542.                 if (strcmpi("Content-Encoding", field)==0)
  543.                     strcpy(info->content_encoding, entry);
  544.                 else if (strcmpi("Content-Length", field)==0)
  545.                     info->content_length=atol(entry);
  546.                 else if (strcmpi("Content-Type", field)==0)
  547.                     strcpy(info->content_type, entry);
  548.                 else if (strcmpi("Location", field)==0)
  549.                     strcpy(info->location, entry);
  550.                 else if (strcmpi("MIME-Version", field)==0)
  551.                     info->mime_version=atof(entry);
  552.                 else if (strcmpi("Pragma", field)==0)
  553.                     strcpy(info->pragma, entry);
  554.                 else if (strcmpi("Server", field)==0)
  555.                     strcpy(info->server, entry);
  556.                 else if (strcmpi("WWW-Authenticate", field)==0)
  557.                     strcpy(info->www_authenticate, entry);
  558.                 else if (strcmpi("Last-Modified", field)==0) {
  559.                     info->last_modified=parse_date(entry);
  560.                     #ifdef MDEBUG
  561.                         printf("%s\n", entry);
  562.                     #endif
  563.                 } else if (strcmpi("Date", field))
  564.                     info->date=parse_date(entry);
  565.                 else if (strcmpi("Expires", field))
  566.                     info->expires=parse_date(entry);
  567.             } else {
  568.                 eoh=1;
  569.             }
  570.         }
  571.     }
  572.     return(return_code);
  573. }
  574.  
  575. time_t parse_date(char *date_string)
  576. {
  577.     size_t index;
  578.     char tmp[5]={0, 0, 0, 0, 0};
  579.     struct tm time;
  580.  
  581.     if (strchr(date_string, '-')!=NULL) {
  582.         /* Sunday, 06-Nov-94 08:49:37 GMT    RFC 850, obsoleted by RFC 1036 */
  583.         index=strcspn(date_string, ",");
  584.         time.tm_sec=atoi(strncpy(tmp, &date_string[index+18], 2));
  585.         time.tm_min=atoi(strncpy(tmp, &date_string[index+15], 2));
  586.         time.tm_hour=atoi(strncpy(tmp, &date_string[index+12], 2));
  587.         time.tm_year=atoi(strncpy(tmp, &date_string[index+9], 2));
  588.         time.tm_mday=atoi(strncpy(tmp, &date_string[index+2], 2));
  589.     } else if (strchr(date_string, ',')!=NULL) {
  590.         /* Sun, 06 Nov 1994 08:49:37 GMT    RFC 822, updated by RFC 1123 */
  591.         time.tm_sec=atoi(strncpy(tmp, &date_string[23], 2));
  592.         time.tm_min=atoi(strncpy(tmp, &date_string[20], 2));
  593.         time.tm_hour=atoi(strncpy(tmp, &date_string[17], 2));
  594.         time.tm_mday=atoi(strncpy(tmp, &date_string[5], 2));
  595.         time.tm_year=atoi(strncpy(tmp, &date_string[12], 4))-1900;
  596.     } else {
  597.         /* Sun Nov  6 08:49:37 1994            ANSI C's asctime() format */
  598.         time.tm_sec=atoi(strncpy(tmp, &date_string[17], 2));
  599.         time.tm_min=atoi(strncpy(tmp, &date_string[14], 2));
  600.         time.tm_hour=atoi(strncpy(tmp, &date_string[11], 2));
  601.         time.tm_mday=atoi(strncpy(tmp, &date_string[8], 2));
  602.         time.tm_year=atoi(strncpy(tmp, &date_string[20], 4))-1900;
  603.     }
  604.     /* The month is generic... */
  605.     if (strstr(date_string, "Jan")>0)
  606.         time.tm_mon=0;
  607.     else if (strstr(date_string, "Feb")>0)
  608.         time.tm_mon=1;
  609.     else if (strstr(date_string, "Mar")>0)
  610.         time.tm_mon=2;
  611.     else if (strstr(date_string, "Apr")>0)
  612.         time.tm_mon=3;
  613.     else if (strstr(date_string, "May")>0)
  614.         time.tm_mon=4;
  615.     else if (strstr(date_string, "Jun")>0)
  616.         time.tm_mon=5;
  617.     else if (strstr(date_string, "Jul")>0)
  618.         time.tm_mon=6;
  619.     else if (strstr(date_string, "Aug")>0)
  620.         time.tm_mon=7;
  621.     else if (strstr(date_string, "Sep")>0)
  622.         time.tm_mon=8;
  623.     else if (strstr(date_string, "Oct")>0)
  624.         time.tm_mon=9;
  625.     else if (strstr(date_string, "Nov")>0)
  626.         time.tm_mon=10;
  627.     else
  628.         time.tm_mon=11;
  629.     /* DOSTIME is in 2 second intervals... */
  630.     time.tm_sec=(time.tm_sec & 0xFFFE);
  631. /*    printf("%ld\n", (long) mktime(&time));*/
  632.     return(mktime(&time));
  633. }
  634.  
  635. void clear_info(URL_info *info)
  636. {
  637.     info->content_encoding[0]=
  638.     info->content_type[0]=
  639.     info->location[0]=
  640.     info->pragma[0]=
  641.     info->server[0]=
  642.     info->www_authenticate[0]=0;
  643.     info->mime_version=
  644.     info->content_length=
  645.     info->date=
  646.     info->expires=
  647.     info->last_modified=-1;
  648. }
  649.  
  650. void split_URL(char *URL, URL_components *components)
  651. {
  652.     size_t colon_index, slash_index;
  653.  
  654.     colon_index=strcspn(URL, ":");
  655.     strncpy(components->protocol, URL, colon_index);
  656.     components->protocol[colon_index]=0;
  657.     strcpy(components->URI, &URL[colon_index+3]);
  658.     slash_index=strcspn(components->URI, "/");
  659.     strncpy(components->server, components->URI, slash_index);
  660.     components->server[slash_index]=0;
  661.     strcpy(components->URI, &URL[colon_index+slash_index+3]);
  662.     colon_index=strcspn(components->server, ":");
  663.     if (colon_index<strlen(components->server)) {
  664.         components->port=atoi(&(components->server[colon_index+1]));
  665.         components->server[colon_index]=0;
  666.     } else {
  667.         components->port=80;
  668.     }
  669. }
  670.  
  671. typedef struct {
  672.     long cktag;
  673.     long ckvalue;
  674. } ck_entry;
  675.  
  676. static long init_drivers(void)
  677. {
  678.     long i = 0;
  679.     ck_entry *jar = *((ck_entry **) 0x5a0);
  680.  
  681.     while (jar[i].cktag) {
  682.         if (!strncmp((char *)&jar[i].cktag, CJTAG, 4)) {
  683.             drivers = (DRV_LIST *)jar[i].ckvalue;
  684.             return (0);
  685.         }
  686.         ++i;
  687.     }
  688.     return (0);    /* Pointless return value...    */
  689. }
  690.  
  691. int http_proxy_cfg(char *ps, int pslen, int *pp){    char *ptr;    #ifdef MDEBUG
  692.         printf("Getting proxy...\n");
  693.     #endif
  694.     ptr = getvstr("HTTP_PROXY");    if (ptr[0] == '0' || ptr[0] == '1')        return (FALSE);    strncpy(ps, ptr, (size_t)pslen);    #ifdef MDEBUG
  695.         printf("Getting proxy port...\n");
  696.     #endif
  697.     ptr = getvstr("HTTP_PROXY_PORT");    /* If there is some kind of standard proxy port, then we could     *use it as a default instead of return (FALSE) here...     */    if (ptr[0] == '0' || ptr[0] == '1')        return (FALSE);    *pp = atoi(ptr);    #ifdef MDEBUG
  698.         printf("Got proxy...\n");
  699.     #endif
  700.     return (TRUE);}
  701. int ftp_proxy_cfg(char *ps, int pslen, int *pp){    char *ptr;    ptr = getvstr("FTP_PROXY");    if (ptr[0] == '0' || ptr[0] == '1')        return (FALSE);    strncpy(ps, ptr, (size_t)pslen);    ptr = getvstr("FTP_PROXY_PORT");    /* If there is some kind of standard proxy port, then we could     *use it as a default instead of return (FALSE) here...     */    if (ptr[0] == '0' || ptr[0] == '1')        return (FALSE);    *pp = atoi(ptr);    return (TRUE);}
  702. /** Resolves server into an IP address, then opens a connection to port
  703.     of server, with TOS (magic variable, which should always be 0, ask
  704.     Steve Adam about it). It returns a connection handle for following
  705.     calls. If it's smaller than 0 then it's an error. */
  706. int16 open_connection(char *server, int port, int TOS)
  707. {
  708.     int16 x, cn;
  709.     uint32 addr;
  710.  
  711.     #ifdef MDEBUG
  712.         printf("open_connection(%s, %i, %i)\n", server, port, TOS);
  713.     #endif
  714.  
  715.     browser->msg_status(4,0);    /* Resolving... */
  716.     x = resolve(server, (char **)NULL, &addr, 1);
  717.     if (x<0) {
  718.         #ifdef ERR_MSGS
  719.             printf("Resolve for %s returns: %s\n", server, get_err_text(x));
  720.         #endif
  721.         return(x);
  722.     }
  723.  
  724.     browser->msg_status(1, 0);    /* Opening connection... */
  725.     cn=TCP_open(addr, port, TOS, 1024);
  726.     if (cn<0) {
  727.         #ifdef ERR_MSGS
  728.             printf("TCP_open() returns: %s\n", get_err_text(cn));
  729.         #endif
  730.         return(cn);
  731.     }
  732.  
  733.     x = TCP_wait_state(cn, TESTABLISH, 60);
  734.     if (x<0) {
  735.         #ifdef ERR_MSGS
  736.             printf("TCP_wait_state() returns: %s\n", get_err_text(x));
  737.         #endif
  738.         TCP_close(cn, 2);
  739.         return(x);
  740.     }
  741.  
  742.     return(cn);
  743. }
  744.